﻿namespace IconPatcher
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Reflection;
    using System.Security.Principal;

    using ManyConsole;

    class Program
    {
        internal static bool Support2010 = true;
        internal static bool Support2012 = true;
        internal static string[] Languages2010;
        internal static string[] Languages2012;

        private static void Main(string[] args)
        {
            if (!new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator))
            {
                BetterConsoleCommand.ErrorMessage("You must be running as an administrator to use this.");
                return;
            }

            Setup(args);

            var commands = GetCommands();

            var consoleRunner = new ConsoleModeCommand(GetCommands);
            commands = commands.Concat(new[] { consoleRunner });

            if (!LoadLanguages())
            {
                return;
            }

            ConsoleCommandDispatcher.DispatchCommand(commands, new[] { consoleRunner.Command }, Console.Out);
        }

        private static IEnumerable<ConsoleCommand> GetCommands()
        {
            return ConsoleCommandDispatcher.FindCommandsInSameAssemblyAs(typeof(Program)).ToList();
        }

        public static string Version()
        {
            return Assembly.GetExecutingAssembly().GetName().Version.ToString(4);
        }

        private static void Setup(string[] args)
        {
            Console.WriteLine("Version: " + Version());
            Console.WriteLine();

            if (args != null && args.Length == 1)
            {
                var command = args[0];

                if (string.Equals(command, "extractmode", StringComparison.OrdinalIgnoreCase))
                {
                    BetterConsoleCommand.SuccessMessage("You are now in extract mode");
                    BetterConsoleCommand.SuccessMessage("You may not access features that work against Visual Studio 2012.");
                    Support2012 = false;
                }
                else if (string.Equals(command, "injectmode", StringComparison.OrdinalIgnoreCase))
                {
                    BetterConsoleCommand.SuccessMessage("You are now in inject mode");
                    BetterConsoleCommand.SuccessMessage("You may not access features that work against Visual Studio 2010.");
                    Support2010 = false;
                }
            }

            if (Support2010 && Support2012)
            {
                Console.WriteLine("By default this tool assumes both Visual Studio 2010 and 2012 are installed.");
                Console.WriteLine();
                Console.WriteLine("Options:");
                Console.WriteLine("    extractmode - extract icons on a machine without VS2012 installed");
                Console.WriteLine();
                Console.WriteLine("    injectmode - inject icons on a machine without VS2010 installed");
                Console.WriteLine();
                Console.WriteLine("Example:");
                Console.WriteLine("    vsip.exe injectmode");
            }

            Console.WriteLine(new string('-', 74));
        }

        private static bool LoadLanguages()
        {
            if (Support2010 && !LoadLanguagesFor2010(out Languages2010))
            {
                return false;
            }

            if (Support2012 && !LoadLanguagesFor2012(out Languages2012))
            {
                return false;
            }

            return true;
        }

        private static bool LoadLanguagesFor2010(out string[] allLanguages)
        {
            allLanguages = new string[0];

            var edition = VisualStudio2010.InstalledEdition();
            if (edition == VisualStudio2010.Edition.Undefined)
            {
                BetterConsoleCommand.ErrorMessage("Unable to find an installed edition of Visual Studio 2010.");
                return false;
            }

            allLanguages = VisualStudio2010.AllLanguages(edition);
            return true;
        }

        private static bool LoadLanguagesFor2012(out string[] allLanguages)
        {
            allLanguages = new string[0];

            var edition = VisualStudio2012.InstalledEdition();
            if (edition == VisualStudio2012.Edition.Undefined)
            {
                BetterConsoleCommand.ErrorMessage("Unable to find an installed edition of Visual Studio 2012.");
                return false;
            }

            allLanguages = VisualStudio2012.AllLanguages(edition);
            return true;
        }
    }
}